<template>
    <!-- 数字输入框 -->
    <div :style="item.style||{}"
         :class="getClass()"
         class="form-item-box">
        <template v-if="!getTextModel">
            <el-input v-model.trim="tempVal"
                      :placeholder="getPlaceholder(item)"
                      :disabled="getDisabled"
                      class="input-wr"
                      type="number"
                      @keydown.native="onKeydown($event)"
                      @blur="e => onBlur(item, e)"
                      @focus="e => onFocus(item, e)"
                      v-bind="bindOptions"
                      :clearable="true">
                <template slot="prepend" v-if="prepend">{{ prepend }}</template>
                <template slot="append" v-if="append">{{ append }}</template>
            </el-input>
            <el-input v-model.trim="dealInputValue"
                      :placeholder="getPlaceholder(item)"
                      :disabled="getDisabled"
                      class="input-readonly"
                      type="input"
                      v-bind="bindOptions"
                      :clearable="true">
                <template slot="prepend" v-if="prepend">{{ prepend }}</template>
                <template slot="append" v-if="append">{{ append }}</template>
            </el-input>
        </template>
        <div v-else :style="item.textStyle||{}">
            {{ prepend }}
            {{ dealInputValue || '-' }}
            {{ append }}
        </div>
    </div>
</template>

<script>
    /* 配置属性：
    * positive：默认 false，true 的时候禁止输入负号（但理论上 js 给的负数值不会变化，下同）；
    * onlyInt：默认 false，true 的时候禁止输入小数点；
    * zeroPadding：默认为空，number 类型，指自动补零到指定位数；
    * decimalLimit：默认为空，number 类型，最大小数位数，小数位数超过这个长度的部分，将被自动截掉；
    * prefix：默认为空，string 类型，前置符号；
    * suffix：默认为空，string 类型，后置符号；
    * */
    import FormMixin from './mixin';

    export default {
        name: 'FormNumberInput',
        mixins: [ FormMixin ],
        data () {
            return {
                readonly: true,
                // 在编辑模式下，使用这个 tempVal 替代真实的 val
                // 在触发 blur 事件时，用这个更新原来的 val
                tempVal: '',
            };
        },
        computed: {
            // 千分位的数字
            dealInputValue () {
                if (this.value === '') {
                    return '';
                }
                const n = String(this.value);
                const res = n.toString().replace(/\d+/, (n) => {
                    return n.replace(/(\d)(?=(\d{3})+$)/g, ($1) => {
                        return $1 + ',';
                    });
                });
                return res;
            },
            // 前置符号
            prepend () {
                // 兼容性处理
                if (this.item.prepend) {
                    return this.item.prepend;
                } else if (this.item.prefixMsg) {
                    return this.item.prefixMsg;
                } else if (this.item.symbolBeforeMsg) {
                    return this.item.symbolBeforeMsg;
                } else {
                    return '';
                }
            },
            // 后置符号
            append () {
                // 兼容性处理
                if (this.item.append) {
                    return this.item.append;
                } else if (this.item.suffixMsg) {
                    return this.item.suffixMsg;
                } else if (this.item.symbolAfterMsg) {
                    return this.item.symbolAfterMsg;
                } else {
                    return '';
                }
            },
            val: {
                get () {
                    if (this.value === '') {
                        return '';
                    }
                    return this.value;
                },
                set (v) {
                    if (v === '') {
                        this.$emit('input', v);
                        // 只有非子表单的情况下，才会冒泡上去数据变更
                        if (this.formItemType !== 'childForm') {
                            this.statusChangeFn.valueUpdateEvent({
                                [this.item.key]: n,
                            });
                        } else {
                            // 如果是子表单的话，执行内置的变更
                            this.childChangeData.valueUpdateEvent();
                        }
                        return;
                    }
                    const newVal = v;
                    let n = String(newVal);
                    // 假如禁止输入负数，那么小于 0 则自动变为 0
                    if (this.item.positive && n && Number(n) < 0) {
                        n = '0';
                    }

                    // 这里主要目的是限制小数位数超过限制的
                    if (
                        (this.item.decimalLimit && this.item.decimalLimit > 0) ||
                        (this.item.zeroMsg && this.item.zeroMsg > 0)
                    ) {
                        // 兼容性设置
                        const limit = this.item.decimalLimit || this.item.zeroMsg;

                        // 包含小数点，并且小数点后面有数字
                        if (n.includes('.') && n.split('.').length > 1) {
                            const currentLength = n.split('.')[1].length;
                            if (currentLength > limit) {
                                const s = n.split('.');
                                n = `${s[0]}.${s[1].slice(0, limit)}`;
                            }
                        }
                    }

                    // 假如禁止输入负数，那么小于 0 则自动变为 0
                    if (this.item.positive && n && Number(n) < 0) {
                        n = '0';
                    }
                    this.$emit('input', n);

                    // 只有非子表单的情况下，才会冒泡上去数据变更
                    if (this.formItemType !== 'childForm') {
                        this.statusChangeFn.valueUpdateEvent({
                            [this.item.key]: n,
                        });
                    } else {
                        // 如果是子表单的话，执行内置的变更
                        this.childChangeData.valueUpdateEvent();
                    }
                }
            }
        },
        methods: {
            onKeydown (e) {
                // 假如禁止输入负数，那么干掉负号
                if (this.item.positive) {
                    if (e.key === '-' || e.code === 'Minus') {
                        e.preventDefault();
                        return;
                    }
                }
                // 假如只允许输入整数，那么干掉小数点
                if (this.item.onlyInt) {
                    if (e.key === '.' || e.code === 'Period') {
                        e.preventDefault();
                        return;
                    }
                }
            },
            getClass () {
                const c1 = `form-unqiue-${this.item.key}`;
                const c2 = this.readonly ? 'is-readonly' : 'is-wr';
                return {
                    [c1]: true,
                    [c2]: true
                };
            },
            onBlur () {
                this.readonly = true;
                if (this.tempVal === '') {
                    this.$emit('input', this.tempVal);

                    this.statusChangeFn.valueUpdateEvent({
                        [this.item.key]: this.tempVal,
                    });
                    return;
                }

                let newVal = this.tempVal;

                // 如果需要补零
                if (this.item.zeroPadding && this.item.zeroPadding > 0) {
                    const l = String(newVal).split('.');
                    // 如果没有小数点（说明只有整数位），自动补零
                    if (l.length === 1) {
                        // 判断 l[0].length 是否为 0，为 0 则说明没填，啥事都不做
                        if (l[0].length === 0) {
                            newVal = '';
                        } else {
                            // 自动补零
                            newVal += '.' + '0'.padEnd(this.item.zeroPadding, '0');
                        }
                    } else {
                        // 此时说明有小数点，那么小数位数多，则去掉多余的。位数小，则补零
                        const currentLength = l[1].length;
                        // 小数位数少，则补零
                        if (currentLength < this.item.zeroPadding) {
                            newVal = l[0] + '.' + l[1].padEnd(this.item.zeroPadding, '0');
                        }
                        // 如果大于
                        if (currentLength > this.item.zeroPadding) {
                            newVal = String(l[0]) + '.' + l[1].slice(0, this.item.zeroPadding);
                        }
                    }
                }
                newVal = String(newVal);
                newVal = newVal.split('.').map((s, index) => {
                    if (index !== 0) {
                        return s;
                    }
                    // 通过正则，匹配首位开始的所有 0（用于去除整数部分开始的 0）
                    const newS = s.replace(/$0+/g, '');
                    // 如果只有 0，那么最后返回 0，确保小数点前有数字
                    if (newS.length === 0) {
                        return '0';
                    } else {
                        return newS;
                    }
                }).join('.');

                // 假如禁止输入负数，那么小于 0 则自动变为 0
                if (this.item.positive && newVal < 0) {
                    newVal = 0;
                }

                this.tempVal = this.throwPointLeftZero(this.tempVal);
                this.tempVal = this.throwPointRightZero(this.tempVal);
                this.val = newVal;
            },
            onFocus () {
                const newValue = this.value;
                this.tempVal = String(newValue);
                this.readonly = false;
            },
        },
    };
</script>

<style scoped lang="less">

    .form-item-box /deep/ .el-input__inner {
        height: 36px;
        line-height: 36px;
    }


    .input-wr {
        z-index: 100;
    }

    .input-readonly {
        position: absolute;
        left: 0;
        top: 0;
    }

    .is-wr {
        .input-wr {
            opacity: 1;
        }

        .input-readonly {
            display: none;
        }
    }

    .is-readonly {
        .input-wr {
            opacity: 0;
        }

        .input-readonly {
            //display: none;
        }
    }

</style>
